#include "dev/time.h"
#include "cpu/irq.h"
#include "comm/types.h"
#include "comm/cpu_instr.h"
#include "os_cfg.h"
#include "core/task.h"

static uint32_t sys_tick;

void do_handler_time(exception_frame_t * frame) {
    sys_tick ++;
    // 本函数必须在任务切换函数前面，以及时响应中断
    irq_send_eoi(IRQ0_TIMER);

    
    // 任务定时方面的处理
    task_time_tick();
}

static void init_pit() {
    // reload_count表示系统10ms时钟中断发生一次需要的节拍数
    uint32_t reload_count = OS_TICKS_MS * PIT_OSC_FREQ / 1000.0;
    outb(PIT_COMMAND_MODE_PORT, PIT_CHANNEL0 | PIT_LOAD_LOHI | PIT_MODE3 
        | PIT_COUNTER_MODE);
    // 发送定时器递减计数值，计时器每递减reload_count个节拍引发一次时钟中断
    outb(PIT_CHANNEL0_DATA_PORT, reload_count & 0xFF);
    outb(PIT_CHANNEL0_DATA_PORT, (reload_count >> 8) & 0xFF);

    irq_install(IRQ0_TIMER, (irq_handler_t)exception_handler_time);
    irq_enable(IRQ0_TIMER);
}

void time_init(void) {
    sys_tick = 0;
    init_pit();
}